// 定义数组结构
let c1: number[] = [1, 2, 3];
let c2: any[] = [false, 2, 3, '4'];
let c3: (number | string)[] = [1, '1'];
let c4: Array<any> = [1, 2, 3, '4'];

// 定义元组结构
let d1: [number, string] = [1, '1'];

// 定义枚举
enum Gender { male = 0, female = 1 }
let e1: { name: string, gender: Gender } = { name: 'aa', gender: Gender.male };
let e2: Gender = Gender.female;

// type与interface，| 或，? 可选， [propName: string]: any 任意，readonly只读
type a1Type = { name: string | number, age?: number, [propName: string]: any };
let a1: a1Type = { name: 'sdf', age: 12, gender: '男' };
interface a2Interface { name: string | number, readonly age?: number, [propName: string]: any, say(info: string): void };
let a2: a2Interface = { name: 123, age: 12, say(){}};

// 定义函数结构
let b1 = function(a: number, b:number): number {
  return a + b;
}
type aaa = (a: number, b:number) => number
let b2: aaa = (a: number, b:number): number => {
  return a + b;
}

// 类型断言
const some: unknown = 123;
let len: number = (some as string).length;
// 类型强转
let laa: number = (<string> some).length

// 抽象类不能实例化
abstract class Animal {
  name: string;
  // 静态属性
  static age: number = 22;
  constructor(name: string) {
    this.name = name;
  }
  // 抽象类里可以有抽象方法 不用实现
  abstract say(who: string): string;
}
class Dog extends Animal {
  // 继承抽象类后必须实现抽象方法
  say(who: string): string {
    return `${this.name}(${Animal.age}) is say hello to ${who}`
  }
}
class Cat extends Animal {
  constructor(name: string) {
    super(name);
    this.name = name + 11;
  }
  say(who: string): string {
    return `${this.name}(${Animal.age}) is say hello to ${who}`
  }
}
const dog: Animal = new Dog('汪汪');
// console.log(dog.say('嘻嘻哥'));
const cat: Cat = new Cat('喵喵');
// console.log(cat.say('哈哈哥'));

// 接口
interface MyInterface {
  name: string;
  say(who: string): string;
}
class MyClass implements MyInterface {
  // implements接口后 name say必须实现
  name: string;
  constructor() {
    this.name = 'aa';
  }
  say(who: string): string {
    return who;
  };
}

// public private protect get set
class Person {
  private name: string;
  private age: number;
  constructor(nameValue: string, ageValue: number) {
    this.name = nameValue;
    this.age = ageValue;
  }
  getName() {
    return this.name;
  }
  getAge() {
    return this.age
  }
  setName(value: string) {
    this.name = value;
  }
  setAge(value: number) {
    if(value > 0) {
      this.age = value;
    }
  }
}
const p = new Person("张三", 11);
p.setAge(-22);
// console.log(p)

// 泛型
function fn<T>(a: T): T {
  return a;
}
const f1 = fn<number>(10);
const f2 = fn<string>('aa');
interface Inter {
  length: number;
}
function fnn<T extends Inter>(a: T): number {
  return a.length;
}
// string也有length属性
fnn('123')
fnn({ length: 122 })

// 假设引入现成的js库lib\globalTitle.js，为它写声明文件lib\globalTitle.d.ts
setTitle('11')
console.log(getTitle())

